home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / arch / x86 / include / asm / floppy.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  6.4 KB  |  282 lines

  1. /*
  2.  * Architecture specific parts of the Floppy driver
  3.  *
  4.  * This file is subject to the terms and conditions of the GNU General Public
  5.  * License.  See the file "COPYING" in the main directory of this archive
  6.  * for more details.
  7.  *
  8.  * Copyright (C) 1995
  9.  */
  10. #ifndef _ASM_X86_FLOPPY_H
  11. #define _ASM_X86_FLOPPY_H
  12.  
  13. #include <linux/vmalloc.h>
  14.  
  15. /*
  16.  * The DMA channel used by the floppy controller cannot access data at
  17.  * addresses >= 16MB
  18.  *
  19.  * Went back to the 1MB limit, as some people had problems with the floppy
  20.  * driver otherwise. It doesn't matter much for performance anyway, as most
  21.  * floppy accesses go through the track buffer.
  22.  */
  23. #define _CROSS_64KB(a, s, vdma)                        \
  24.     (!(vdma) &&                            \
  25.      ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64))
  26.  
  27. #define CROSS_64KB(a, s) _CROSS_64KB(a, s, use_virtual_dma & 1)
  28.  
  29.  
  30. #define SW fd_routine[use_virtual_dma & 1]
  31. #define CSW fd_routine[can_use_virtual_dma & 1]
  32.  
  33.  
  34. #define fd_inb(port)        inb_p(port)
  35. #define fd_outb(value, port)    outb_p(value, port)
  36.  
  37. #define fd_request_dma()    CSW._request_dma(FLOPPY_DMA, "floppy")
  38. #define fd_free_dma()        CSW._free_dma(FLOPPY_DMA)
  39. #define fd_enable_irq()        enable_irq(FLOPPY_IRQ)
  40. #define fd_disable_irq()    disable_irq(FLOPPY_IRQ)
  41. #define fd_free_irq()        free_irq(FLOPPY_IRQ, NULL)
  42. #define fd_get_dma_residue()    SW._get_dma_residue(FLOPPY_DMA)
  43. #define fd_dma_mem_alloc(size)    SW._dma_mem_alloc(size)
  44. #define fd_dma_setup(addr, size, mode, io) SW._dma_setup(addr, size, mode, io)
  45.  
  46. #define FLOPPY_CAN_FALLBACK_ON_NODMA
  47.  
  48. static int virtual_dma_count;
  49. static int virtual_dma_residue;
  50. static char *virtual_dma_addr;
  51. static int virtual_dma_mode;
  52. static int doing_pdma;
  53.  
  54. static irqreturn_t floppy_hardint(int irq, void *dev_id)
  55. {
  56.     unsigned char st;
  57.  
  58. #undef TRACE_FLPY_INT
  59.  
  60. #ifdef TRACE_FLPY_INT
  61.     static int calls;
  62.     static int bytes;
  63.     static int dma_wait;
  64. #endif
  65.     if (!doing_pdma)
  66.         return floppy_interrupt(irq, dev_id);
  67.  
  68. #ifdef TRACE_FLPY_INT
  69.     if (!calls)
  70.         bytes = virtual_dma_count;
  71. #endif
  72.  
  73.     {
  74.         int lcount;
  75.         char *lptr;
  76.  
  77.         st = 1;
  78.         for (lcount = virtual_dma_count, lptr = virtual_dma_addr;
  79.              lcount; lcount--, lptr++) {
  80.             st = inb(virtual_dma_port + 4) & 0xa0;
  81.             if (st != 0xa0)
  82.                 break;
  83.             if (virtual_dma_mode)
  84.                 outb_p(*lptr, virtual_dma_port + 5);
  85.             else
  86.                 *lptr = inb_p(virtual_dma_port + 5);
  87.         }
  88.         virtual_dma_count = lcount;
  89.         virtual_dma_addr = lptr;
  90.         st = inb(virtual_dma_port + 4);
  91.     }
  92.  
  93. #ifdef TRACE_FLPY_INT
  94.     calls++;
  95. #endif
  96.     if (st == 0x20)
  97.         return IRQ_HANDLED;
  98.     if (!(st & 0x20)) {
  99.         virtual_dma_residue += virtual_dma_count;
  100.         virtual_dma_count = 0;
  101. #ifdef TRACE_FLPY_INT
  102.         printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n",
  103.                virtual_dma_count, virtual_dma_residue, calls, bytes,
  104.                dma_wait);
  105.         calls = 0;
  106.         dma_wait = 0;
  107. #endif
  108.         doing_pdma = 0;
  109.         floppy_interrupt(irq, dev_id);
  110.         return IRQ_HANDLED;
  111.     }
  112. #ifdef TRACE_FLPY_INT
  113.     if (!virtual_dma_count)
  114.         dma_wait++;
  115. #endif
  116.     return IRQ_HANDLED;
  117. }
  118.  
  119. static void fd_disable_dma(void)
  120. {
  121.     if (!(can_use_virtual_dma & 1))
  122.         disable_dma(FLOPPY_DMA);
  123.     doing_pdma = 0;
  124.     virtual_dma_residue += virtual_dma_count;
  125.     virtual_dma_count = 0;
  126. }
  127.  
  128. static int vdma_request_dma(unsigned int dmanr, const char *device_id)
  129. {
  130.     return 0;
  131. }
  132.  
  133. static void vdma_nop(unsigned int dummy)
  134. {
  135. }
  136.  
  137.  
  138. static int vdma_get_dma_residue(unsigned int dummy)
  139. {
  140.     return virtual_dma_count + virtual_dma_residue;
  141. }
  142.  
  143.  
  144. static int fd_request_irq(void)
  145. {
  146.     if (can_use_virtual_dma)
  147.         return request_irq(FLOPPY_IRQ, floppy_hardint,
  148.                    IRQF_DISABLED, "floppy", NULL);
  149.     else
  150.         return request_irq(FLOPPY_IRQ, floppy_interrupt,
  151.                    IRQF_DISABLED, "floppy", NULL);
  152. }
  153.  
  154. static unsigned long dma_mem_alloc(unsigned long size)
  155. {
  156.     return __get_dma_pages(GFP_KERNEL|__GFP_NORETRY, get_order(size));
  157. }
  158.  
  159.  
  160. static unsigned long vdma_mem_alloc(unsigned long size)
  161. {
  162.     return (unsigned long)vmalloc(size);
  163.  
  164. }
  165.  
  166. #define nodma_mem_alloc(size) vdma_mem_alloc(size)
  167.  
  168. static void _fd_dma_mem_free(unsigned long addr, unsigned long size)
  169. {
  170.     if ((unsigned long)addr >= (unsigned long)high_memory)
  171.         vfree((void *)addr);
  172.     else
  173.         free_pages(addr, get_order(size));
  174. }
  175.  
  176. #define fd_dma_mem_free(addr, size)  _fd_dma_mem_free(addr, size)
  177.  
  178. static void _fd_chose_dma_mode(char *addr, unsigned long size)
  179. {
  180.     if (can_use_virtual_dma == 2) {
  181.         if ((unsigned long)addr >= (unsigned long)high_memory ||
  182.             isa_virt_to_bus(addr) >= 0x1000000 ||
  183.             _CROSS_64KB(addr, size, 0))
  184.             use_virtual_dma = 1;
  185.         else
  186.             use_virtual_dma = 0;
  187.     } else {
  188.         use_virtual_dma = can_use_virtual_dma & 1;
  189.     }
  190. }
  191.  
  192. #define fd_chose_dma_mode(addr, size) _fd_chose_dma_mode(addr, size)
  193.  
  194.  
  195. static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
  196. {
  197.     doing_pdma = 1;
  198.     virtual_dma_port = io;
  199.     virtual_dma_mode = (mode == DMA_MODE_WRITE);
  200.     virtual_dma_addr = addr;
  201.     virtual_dma_count = size;
  202.     virtual_dma_residue = 0;
  203.     return 0;
  204. }
  205.  
  206. static int hard_dma_setup(char *addr, unsigned long size, int mode, int io)
  207. {
  208. #ifdef FLOPPY_SANITY_CHECK
  209.     if (CROSS_64KB(addr, size)) {
  210.         printk("DMA crossing 64-K boundary %p-%p\n", addr, addr+size);
  211.         return -1;
  212.     }
  213. #endif
  214.     /* actual, physical DMA */
  215.     doing_pdma = 0;
  216.     clear_dma_ff(FLOPPY_DMA);
  217.     set_dma_mode(FLOPPY_DMA, mode);
  218.     set_dma_addr(FLOPPY_DMA, isa_virt_to_bus(addr));
  219.     set_dma_count(FLOPPY_DMA, size);
  220.     enable_dma(FLOPPY_DMA);
  221.     return 0;
  222. }
  223.  
  224. static struct fd_routine_l {
  225.     int (*_request_dma)(unsigned int dmanr, const char *device_id);
  226.     void (*_free_dma)(unsigned int dmanr);
  227.     int (*_get_dma_residue)(unsigned int dummy);
  228.     unsigned long (*_dma_mem_alloc)(unsigned long size);
  229.     int (*_dma_setup)(char *addr, unsigned long size, int mode, int io);
  230. } fd_routine[] = {
  231.     {
  232.         request_dma,
  233.         free_dma,
  234.         get_dma_residue,
  235.         dma_mem_alloc,
  236.         hard_dma_setup
  237.     },
  238.     {
  239.         vdma_request_dma,
  240.         vdma_nop,
  241.         vdma_get_dma_residue,
  242.         vdma_mem_alloc,
  243.         vdma_dma_setup
  244.     }
  245. };
  246.  
  247.  
  248. static int FDC1 = 0x3f0;
  249. static int FDC2 = -1;
  250.  
  251. /*
  252.  * Floppy types are stored in the rtc's CMOS RAM and so rtc_lock
  253.  * is needed to prevent corrupted CMOS RAM in case "insmod floppy"
  254.  * coincides with another rtc CMOS user.        Paul G.
  255.  */
  256. #define FLOPPY0_TYPE                    \
  257. ({                            \
  258.     unsigned long flags;                \
  259.     unsigned char val;                \
  260.     spin_lock_irqsave(&rtc_lock, flags);        \
  261.     val = (CMOS_READ(0x10) >> 4) & 15;        \
  262.     spin_unlock_irqrestore(&rtc_lock, flags);    \
  263.     val;                        \
  264. })
  265.  
  266. #define FLOPPY1_TYPE                    \
  267. ({                            \
  268.     unsigned long flags;                \
  269.     unsigned char val;                \
  270.     spin_lock_irqsave(&rtc_lock, flags);        \
  271.     val = CMOS_READ(0x10) & 15;            \
  272.     spin_unlock_irqrestore(&rtc_lock, flags);    \
  273.     val;                        \
  274. })
  275.  
  276. #define N_FDC 2
  277. #define N_DRIVE 8
  278.  
  279. #define EXTRA_FLOPPY_PARAMS
  280.  
  281. #endif /* _ASM_X86_FLOPPY_H */
  282.